<template>
  <div>
    <div class="content">
      <div class="filed" @click="focus">
        <div :class="{ big: !showInput }" class="label">{{ label }}</div>
        <input v-if="showInput" ref="el" class="input" :type="type" v-model="modelValue" @blur="handleBlur" @input="handleInput" :maxlength="maxlength" />
      </div>
      <slot name="right"> </slot>
    </div>
    <div class="error-area">
      {{ errorMsg }}
    </div>
  </div>
</template>

<script setup>
import { computed, nextTick, ref, watch } from 'vue'
import debounce from 'lodash.debounce'
import { useVModels } from '@vueuse/core'

const emit = defineEmits(['update:modelValue', 'update:verifySuccess'])
const props = defineProps({
  // 双向绑定的输入框值
  modelValue: {
    default: '',
  },
  // 双向绑定的输入框验证状态
  verifySuccess: {
    default: false,
  },
  //
  label: {},
  // 校验规则
  rule: {
    default: [],
  },
  // 输入框类型
  type: {
    default: 'text',
  },
  maxlength: {
    type: Number,
    default: 10,
  },
})
const { modelValue, verifySuccess } = useVModels(props, emit)

let showInput = computed(() => {
  return modelValue.value || toFill.value
})

let el = ref()
// 标记当前操作为点击输入
let toFill = ref(false)
function focus() {
  toFill.value = true
  nextTick(() => {
    el.value.focus()
  })
}

let errorMsg = ref()
function verify() {
  console.log('verify')
  let list = props.rule || []
  for (let i = 0; i < list.length; i++) {
    let { required, pattern, message } = list[i]
    // 必填项 & 未填写
    if (required && !modelValue.value) {
      errorMsg.value = message
      return false
    }
    // 有正则 & 不满足
    if (pattern && !pattern.test(modelValue.value)) {
      errorMsg.value = message
      return false
    }
  }
  errorMsg.value = ''
  return true
}

function getVerifyResult() {
  verifySuccess.value = verify()
}

let handleInput = debounce(() => {
  // input type 为 number 的情况下 maxlength 不生效 所以这里做兼容处理
  if (props.type == 'number') {
    let _modelValueString = String(modelValue.value)
    if (_modelValueString > props.maxlength) {
      modelValue.value = _modelValueString.slice(0, props.maxlength)
    }
  }

  // 校验输入合法
  nextTick(getVerifyResult)
}, 200)

function handleBlur() {
  // 离开输入状态
  toFill.value = false
}

defineExpose({
  getVerifyResult,
})
</script>

<style lang="scss" scoped>
.filed {
  flex: 1;
  min-height: 60px;
  background-color: rgba(0, 0, 0, 0.02);
  padding: 8px;
  box-sizing: border-box;
  display: flex;
  flex-flow: column wrap;
  justify-content: center;
  border-bottom: 1px solid black;
  .label {
    transition: all var(--transition-time);
    font-size: 12px;
    font-weight: 700;
    color: rgba(0, 0, 0, 0.4);
  }
  .big {
    font-size: 16px;
  }
  .input {
    border: 0; /*清除自带的2px的边框*/
    padding: 0; /*清除自带的padding间距*/
    outline: none; /*清除input点击之后的黑色边框*/

    margin-top: 5px;
    height: 20px;
    font-weight: 400;
    font-size: 16px;
    color: rgba(0, 0, 0, 1);
    background-color: transparent;
    // background-color: red;
    flex: 1;
  }
}
.content {
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: relative;
}
.error-area {
  margin: 1px 0;
  height: 20px;
  color: #f56c6c;
  font-size: 12px;
  display: flex;
  align-items: center;
}
</style>
